package typconv

import (
	"errors"
	"fmt"
	"strconv"
)

// region AnyToString 将 any 类型转换为 string 类型

func AnyToString(val any) (string, error) {
	switch v := val.(type) {
	case string:
		return v, nil
	case int, int8, int16, int32, int64:
		return fmt.Sprintf("%d", v), nil
	case uint, uint8, uint16, uint32, uint64:
		return fmt.Sprintf("%d", v), nil
	case float32, float64:
		return fmt.Sprintf("%f", v), nil
	case bool:
		return fmt.Sprintf("%t", v), nil
	case []byte:
		return string(v), nil
	default:
		return "", errors.New("unsupported type")
	}
}

func ExampleUsageAnyToString() {
	vals := []any{
		"hello", 42, int8(42), int16(42), int32(42), int64(42),
		uint(42), uint8(42), uint16(42), uint32(42), uint64(42),
		float32(42.42), float64(42.42), true, []byte("byte slice"),
	}

	for _, val := range vals {
		if s, err := AnyToString(val); err == nil {
			fmt.Printf("Converted value: %s\n", s)
		} else {
			fmt.Printf("Error: %s\n", err)
		}
	}
}

// endregion

// region  AnyToInt 将 any 类型转换为 int 类型

func AnyToInt(val any) (int, error) {
	switch v := val.(type) {
	case int:
		return v, nil
	case int8:
		return int(v), nil
	case int16:
		return int(v), nil
	case int32:
		return int(v), nil
	case int64:
		return int(v), nil
	case uint:
		return int(v), nil
	case uint8:
		return int(v), nil
	case uint16:
		return int(v), nil
	case uint32:
		return int(v), nil
	case uint64:
		if v > uint64(^uint(0)>>1) {
			return 0, errors.New("uint64 value is too large to convert to int")
		}
		return int(v), nil
	case float32:
		return int(v), nil
	case float64:
		return int(v), nil
	case string:
		return strconv.Atoi(val.(string))
	default:
		return 0, errors.New("unsupported type")
	}
}
func AnyToIntOK(val any) (int, bool) {
	i, err := AnyToInt(val)
	if err != nil {
		return 0, false
	} else {
		return i, true
	}
}

func ExampleUsageAnyToInt() {
	vals := []any{42, int8(42), int16(42), int32(42), int64(42), uint(42), uint8(42), uint16(42), uint32(42), uint64(42), float32(42.0), float64(42.0), "42"}

	for _, val := range vals {
		if i, err := AnyToInt(val); err == nil {
			fmt.Printf("Converted value: %d\n", i)
		} else {
			fmt.Printf("Error: %s\n", err)
		}
	}
}

// endregion
